<?php

/**
 * LoginForm class.
 * LoginForm is the data structure for keeping
 * user login form data. It is used by the 'login' action of 'SiteController'.
 */
class LoginForm extends CFormModel
{
	public $username;
	public $password;
	public $rememberMe;
	public $verifyCode;

	private $_identity;

	/**
	 * Declares the validation rules.
	 * The rules state that username and password are required,
	 * and password needs to be authenticated.
	 */
	public function rules()
	{
		return array(
			// username and password are required
			array('username, password', 'required'),
			// password needs to be authenticated
			array('password', 'authenticate'),
			
			array('verifyCode', 'CaptchaExtendedValidator', 'allowEmpty'=>!(CCaptcha::checkRequirements() && app()->params['GLOBAL_SETTING']['ENABLED_CAPTCHA'])),
		);
	}

	/**
	 * Declares attribute labels.
	 */
	public function attributeLabels()
	{
		return array(
			'username' => 'Username',
			'password' => 'Password',
			'rememberMe'=>'Remember me next time',
			'verifyCode' => 'Verification Code',
		);
	}
	
	public function getFieldLabel($field)
	{
		$labels = $this->attributeLabels();
		
		return empty($labels[$field])? '' : $labels[$field];
	}

	public function getUser()
	{
		return User::model()->findByAttributes(array('username' => $this->username));
	}
	
	public function validate($attributes = null, $clearErrors = true)
	{
		$ret = parent::validate($attributes, $clearErrors);
		if(!$ret){
			$user = User::model()->findByAttributes(array('username' => $this->username));
			if($user){
				$user->increaseLoginattempts();
				
				if($this->getError('verifyCode') != ''){
					app()->__Whatever__Log->recordLogin($user->id_user, SystemLog::LOGIN_FALIED, SystemLog::LOGIN_FAILED_REASON_CAPTCHA);
				}
				
				if($this->getError('Status') != ''){
					app()->__Whatever__Log->recordLogin($user->id_user, SystemLog::LOGIN_FALIED, SystemLog::LOGIN_FAILED_REASON_SUSPEND);
				}

				if($this->_identity->errorCode === UserIdentity::ERROR_PASSWORD_INVALID){
					app()->__Whatever__Log->recordLogin($user->id_user, SystemLog::LOGIN_FALIED, SystemLog::LOGIN_FAILED_REASON_PWD);
				}
				
				if(app()->params['GLOBAL_SETTING']['MAX_FAILED_LOGIN_ATTEMPTS'] !== 0
				 && $user->loginattempts >= app()->params['GLOBAL_SETTING']['MAX_FAILED_LOGIN_ATTEMPTS']){
					$user->suspend();
					app()->mail->sendSuspendUser($user->id_user);
				}
			}
		}
		
		return $ret;
	}
	
	/**
	 * Authenticates the password.
	 * This is the 'authenticate' validator as declared in rules().
	 */
	public function authenticate()
	{
		if(!$this->hasErrors())
		{
			$this->_identity = new UserIdentity($this->username, $this->password);
			if(!$this->_identity->authenticate()){
				if($this->_identity->errorCode == UserIdentity::ERROR_STATUS_SUSPEND){
					$this->addError('Status', 'This user has been suspended! Check your email for reactivation information.');
				}else{
					$this->addError('Error', 'Incorrect username or password.');
				}
			}
		}
	}

	/**
	 * Logs in the user using the given username and password in the model.
	 * @return boolean whether login is successful
	 */
	public function login()
	{
		if($this->_identity === null){
			$this->_identity = new UserIdentity($this->username, $this->password);
		}
		$this->authenticate();
		
		if($this->_identity->errorCode === UserIdentity::ERROR_NONE){
			$duration = $this->rememberMe ? 3600*24*30 : 0; // 30 days
			app()->user->login($this->_identity, $duration);
			return true;
		}else{
			return false;
		}
	}
}
